package cn.kdyzm.minio.service;

import cn.kdyzm.minio.client.UploadMinioClient;
import io.minio.*;
import io.minio.messages.Bucket;
import io.minio.messages.Item;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * @author kdyzm
 * @date 2022/11/18
 */
@Component
@Slf4j
@AllArgsConstructor
public class MinioBucketService {

    private final UploadMinioClient minioClient;

    /**
     * 创建一个新的存储桶
     *
     * @param bucketName 存储桶名称。
     */
    public void makeBucket(String bucketName) {
        try {
            // 如存储桶不存在，创建之。
            boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            if (found) {
                log.info("{} already exists", bucketName);
            } else {
                // 创建名为'my-bucketname'的存储桶。
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
                log.info("{} is created successfully", bucketName);
            }
        } catch (Exception e) {
            log.error("", e);
        }
    }


    /**
     * 列出所有存储桶
     *
     * @return 存储桶名称。
     */
    public List<Bucket> listBuckets() {
        try {
            // 列出所有存储桶
            return minioClient.listBuckets();
        } catch (Exception e) {
            log.error("", e);
        }
        return new ArrayList<>();
    }

    /**
     * 检查存储桶是否存在。
     *
     * @param bucketName 存储桶名称。
     */
    public boolean bucketExists(String bucketName) {
        try {
            return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
        } catch (Exception e) {
            log.error("", e);
            return false;
        }
    }


    /**
     * 删除一个存储桶。
     *
     * @param bucketName 存储桶名称。
     */
    public void removeBucket(String bucketName) {
        try {
            // 删除之前先检查`my-bucket`是否存在。
            boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            if (found) {
                // 删除`my-bucketname`存储桶，注意，只有存储桶为空时才能删除成功。
                minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());
                log.info("{} is removed successfully", bucketName);
            } else {
                log.info("{} does not exist", bucketName);
            }
        } catch (Exception e) {
            log.error("Error occurred", e);
        }
    }

    /**
     * @param bucketName  String	存储桶名称。
     * @param prefix      String	对象名称的前缀
     * @param recursive   boolean	是否递归查找，如果是false,就模拟文件夹结构查找。
     * @param useVersion1 boolean	如果是true, 使用版本1 REST API
     */
    public List<Item> listObjects(String bucketName, String prefix, boolean recursive, boolean useVersion1) {
        try {
            // 检查'mybucket'是否存在。
            boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            if (found) {
                // 列出'my-bucketname'里的对象
                Iterable<Result<Item>> myObjects = minioClient.listObjects(ListObjectsArgs.builder()
                        .bucket(bucketName)
                        .prefix(prefix)
                        .recursive(recursive)
                        .useApiVersion1(useVersion1)
                        .build()
                );
                List<Item> result = new ArrayList<>();
                myObjects
                        .iterator()
                        .forEachRemaining(item -> {
                            try {
                                result.add(item.get());
                            } catch (Exception e) {
                                log.error("", e);
                            }
                        });
                return result;
            } else {
                log.error("{} does not exist", bucketName);
            }
        } catch (Exception e) {
            log.error("Error occurred", e);
        }
        return new ArrayList<>();
    }

}
